﻿using System;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Data;

namespace Business
{
    public class User : Business.IUser
    {
        #region Properties


        public static string LoginName { get; set; }
        public static string Password { get; set; }


        public string UserName { set; get; }
        public string LoginTime { set; get; }
        public DateTime? LastLoginTime { set; get; }

        public ObservableCollection<IRole> Roles { set; get; }

        #endregion

        #region Singleton Object creation for multithreading safe environment
        /// <summary>
        /// Refer http://msdn.microsoft.com/en-us/library/ff650316.aspx
        /// </summary>
        private static volatile IUser _instance;
        private static object syncRoot = new object();

        /// <summary>
        /// Private constructor so that nobody can create the instance
        /// </summary>
        private User()
        {
        }


        public static IUser Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (syncRoot)
                    {
                        if (_instance == null)
                            _instance = GetUserInstance();
                    }
                }
                return _instance;
            }
        }

        #endregion
        
        #region Methods

        private static IUser GetUserInstance()
        {
            System.Data.DataSet Ds = GetUserData(LoginName, Password);
            IUser UserData = new User()
            {
                UserName = Ds.Tables[0].Rows[0].Field<string>("UserName"),
                LastLoginTime = Ds.Tables[0].Rows[0].Field<DateTime?>("LastLoginTime")
            };

            UserData.Roles = new ObservableCollection<IRole>();

            foreach (DataRow UserRoleData in Ds.Tables[1].Rows)
            {
                IRole UserRole = new Role()
                {
                    Name = UserRoleData.Field<string>("RoleName"),
                    ID = UserRoleData.Field<int>("RoleUniqueKey")
                };

                UserRole.Regions = new ObservableCollection<IRegion>();

                foreach (DataRow UserRoleRegion in Ds.Tables[2].Select("RoleUniqueKey = " + UserRole.ID.ToString()))
                {
                    IRegion RoleRegion = new Region(UserRoleRegion.Field<int>("RegionUniqueKey"))
                    {                        
                        RegionName = UserRoleRegion.Field<string>("RegionName")
                    };
                    UserRole.Regions.Add(RoleRegion);
                }
                UserData.Roles.Add(UserRole);
            }
            return UserData;
        }

        private static System.Data.DataSet GetUserData(string LoginName, string Password)
        {
            System.Data.SqlClient.SqlConnection conn = null;
            System.Data.DataSet DsData = new System.Data.DataSet();
            try
            {
                using (conn = new System.Data.SqlClient.SqlConnection(Database.ConnectionString))
                {
                    conn.Open();
                    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand())
                    {
                        string SQLString = "UP_UserGet";
                        cmd.Connection = conn;
                        cmd.CommandText = SQLString;
                        cmd.CommandType = System.Data.CommandType.StoredProcedure;

                        cmd.Parameters.AddWithValue("@LoginName", LoginName);
                        cmd.Parameters.AddWithValue("@Password", Password);
                        cmd.CommandTimeout = 60;

                        System.Data.SqlClient.SqlDataAdapter AdapData = new System.Data.SqlClient.SqlDataAdapter(cmd);
                        AdapData.Fill(DsData);
                    }
                }
            }
            catch (Exception exception)
            {
                throw exception;
            }

            return DsData;
        }

        #endregion



    }
}
